// OpenGL.cpp
//
#include "OpenGL.h"

#include <iostream>
#include <sstream>
#include "Utils/MemCheck.h"

std::vector<std::string> OpenGL::glExtensions;

static int  supportedMemoryAPI = 0;

//----------------------------------------------------------------------------------------------
bool OpenGL::glInitExtensions()
{
#ifdef _USE_GLEW_
	if( glewInit() == GLEW_OK )
	{
		//std::cout << "Init OpenGL extensions OK" << std::endl;
		return true;
	}
	else
	{
		//std::cout << "Unable to init OpenGL extensions" << std::endl;
		return false;
	}
#endif
	return false;
}

//----------------------------------------------------------------------------------------------
void OpenGL::glDumpContextInfo()
{
	std::string ext   ( (char *)glGetString(GL_EXTENSIONS) );
	std::string vendor( (char *)glGetString(GL_VENDOR) );
	std::string ver   ( (char *)glGetString(GL_VERSION) );
	std::string rend  ( (char *)glGetString(GL_RENDERER) );

	std::stringstream s(ext);

	OpenGL::glExtensions.clear();
	while( !s.eof() )
	{
		std::string str; s >> str;

		if( str.length()>0 )
			OpenGL::glExtensions.push_back( str );
	}

	std::cout << "Graphic Adapter:   " << vendor << std::endl;
	std::cout << "OpenGL Renderer:   " << rend   << std::endl;
	std::cout << "OpenGL Version:    " << ver    << std::endl;
	std::cout << "OpenGL Extensions: " << OpenGL::glExtensions.size() << std::endl;
	std::cout << std::endl;


	if( glSupportMemoryQuery() )	std::cout << "Total Graphic Memory: " <<  (OpenGL::glGetTotalMemory() >> 10) << "MB" << std::endl;
	else							std::cout << "Total Graphic Memory: Unknown" << std::endl;

	std::cout << std::endl;
}


//----------------------------------------------------------------------------------------------
void OpenGL::glCheckError(const char* file, unsigned line)
{
	GLenum err = glGetError();
	if( err != GL_NO_ERROR )
	{
		std::cout << "OpenGL ERROR [ " << err 
			      << " - "             << gluErrorString(err)
				  << " ]   (file "     << std::string(file)
				  << ", "              << line
				  << ")"               << std::endl;
	}
}

//----------------------------------------------------------------------------------------------
bool OpenGL::glSupportMemoryQuery()
{
	static bool first      = true;
	if(first)
	{
		//bool support = false;
		for(size_t i=0; i<glExtensions.size(); ++i)
		{
			if( glExtensions[i] == std::string("GL_NVX_gpu_memory_info") )
				supportedMemoryAPI = 1;

			//if( glExtensions[i] == std::string("GL_ATI_meminfo") )
			//	supportedMemoryAPI = 2;

			//if( glExtensions[i] == std::string("GL_INTEL_performance_query") ) 
			//	supportedMemoryAPI = 3;
		}

		
		first = false;
	}
	
	return supportedMemoryAPI>0;
}

//----------------------------------------------------------------------------------------------
// returns total dedicated memory in KB ( >> 10 to get MB)
int OpenGL::glGetDedicatedTotalMemory()
{
	GLint dedicatedMemKB = 0;
	
	if( glSupportMemoryQuery() )
	{
		switch(supportedMemoryAPI)
		{
		case 1: glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &dedicatedMemKB); break;
		//case 2: glGetIntegerv(GL_ATI_meminfo, &dedicatedMemKB); break;
		//case 3: glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &dedicatedMemKB); break;
		}
	}
	return dedicatedMemKB;
}


//----------------------------------------------------------------------------------------------
// returns available free memory in KB ( >> 10 to get MB)
int OpenGL::glGetFreeMemory()
{
	GLint freeMemKB = 0;
	if( glSupportMemoryQuery() )
		glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &freeMemKB);
	return freeMemKB;
}

//----------------------------------------------------------------------------------------------
// returns total available memory in KB ( >> 10 to get MB)
int OpenGL::glGetTotalMemory()
{
	GLint totalMemKB = 0;
	
	if( glSupportMemoryQuery() )
		glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &totalMemKB);	
	return totalMemKB;
}